package cn.rui.aop;

import cn.rui.pojo.SysLog;
import cn.rui.service.SyLogService;
import cn.rui.utils.HttpContextUtils;
import cn.rui.utils.IpUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @author 徽州大都督
 * @date 2020/8/13
 */
@Aspect
@Component
public class LogAspect {

    @Autowired
    private SyLogService syLogService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Pointcut("@annotation(cn.rui.aop.Log)")
    public void pointcut(){}


    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point) {
        Object result = null;
        long beginTime = System.currentTimeMillis();
        try {
            // 执行方法
            result = point.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        // 执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        // 保存日志
        saveLog(point, time);
        return result;
    }

    private void saveLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SysLog sysLog = new SysLog();
        Log logAnnotation =method.getAnnotation(Log.class);

        if (logAnnotation != null) {
            // 注解上的描述
            sysLog.setOperation(logAnnotation.value());
        }
        // 请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLog.setMethod(className + "." + methodName + "()");
        // 请求的方法参数值



        // 获取request
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();

        String requestURI = request.getRequestURI (); //请求路径
        sysLog.setMethod (requestURI);



        // 设置IP地址
        sysLog.setIp(IpUtils.getIpAddr(request));
        // 模拟一个用户名
        Subject subject = SecurityUtils.getSubject ();
        String principal = (String) subject.getPrincipal ();

        //System.out.println (principal);

        //System.out.println (sysLog);
        //登陆不成功
        if (principal==null){

            if (redisTemplate.opsForValue ().get ("admin_name")!=null){

                sysLog.setUsername ((String) redisTemplate.opsForValue ().get ("admin_name"));
                sysLog.setType (1);
                sysLog.setTypeStr ("操作正常");
                sysLog.setTime((int) time);

            }else {
                if (redisTemplate.opsForValue ().get ("adminUsername")!=null){
                    //密码错误
                    sysLog.setUsername ((String) redisTemplate.opsForValue ().get ("adminUsername"));

                    //System.out.println (redisTemplate.opsForValue ().get ("adminUsername").toString ());
                    sysLog.setType (0);
                    sysLog.setTypeStr ("密码错误");
                    sysLog.setTime((int) time);
                    redisTemplate.delete ("adminUsername");
                }else {
                    //用户名错误不记录日志
                    return;
                }
            }

        }else {
            sysLog.setType (1);
            sysLog.setTypeStr ("操作正常");
            sysLog.setUsername(principal);
            sysLog.setTime((int) time);
            //sysLog.setCreateTime(new Date ());
        }

        //System.out.println (sysLog);
        //保存到数据库
        syLogService.addLog (sysLog);
    }
}
